package com.modakai.med.hosp.service.impl;

import com.alibaba.fastjson2.JSONObject;
import com.modakai.med.common.exception.MedException;
import com.modakai.med.common.result.ResultCodeEnum;
import com.modakai.med.hosp.repository.DepartmentRepository;
import com.modakai.med.hosp.service.DepartmentService;
import com.modakai.med.model.hosp.Department;
import com.modakai.med.vo.DepartmentQueryVo;
import com.modakai.med.vo.DepartmentVo;
import lombok.RequiredArgsConstructor;
import org.springframework.data.domain.*;
import org.springframework.stereotype.Service;

import java.util.*;
import java.util.stream.Collectors;

@Service
@RequiredArgsConstructor
public class DepartmentServiceImpl implements DepartmentService {

    private final DepartmentRepository departmentRepository;

    @Override
    public void save(Map<String, Object> paramMap) {
        Department department = JSONObject.parseObject(JSONObject.toJSONString(paramMap), Department.class);

        // 判断是否存在
        String depcode = department.getDepcode();
        Department targetDepartment = departmentRepository.getDepartmentByHoscodeAndDepcode(department.getHoscode(), depcode);
        if (targetDepartment != null) {
            targetDepartment.setUpdateTime(new Date());
            targetDepartment.setIsDeleted(0);
            departmentRepository.save(targetDepartment);
        } else {
            department.setCreateTime(new Date());
            department.setUpdateTime(new Date());
            department.setIsDeleted(0);
        }
        departmentRepository.save(department);
    }

    @Override
    public Page<Department> selectPage(Integer page, Integer limit, DepartmentQueryVo departmentQueryVo) {
        // 1 排序
        Sort sort = Sort.by(Sort.Direction.DESC, "createTime");
        PageRequest pageable = PageRequest.of(page - 1, limit, sort);
        // 2 条件
        Department department = new Department();
        department.setHoscode(departmentQueryVo.getHoscode());
        department.setDepcode(departmentQueryVo.getDepcode());
        department.setIsDeleted(0);

        //创建匹配器，即如何使用查询条件
        ExampleMatcher exampleMatcher = ExampleMatcher.matching()
                .withStringMatcher(ExampleMatcher.StringMatcher.CONTAINING) // 修改默认字符集
                .withIgnoreCase(true);//改变默认大小写忽略方式：忽略大小写

        // 创建实例
        Example<Department> example = Example.of(department, exampleMatcher);
        return departmentRepository.findAll(example, pageable);
    }

    @Override
    public void remove(String hoscode, String depcode) {
        Department department = departmentRepository.getDepartmentByHoscodeAndDepcode(hoscode, depcode);
        if (null != department) {
            departmentRepository.deleteById(department.getId());
        }
    }

    @Override
    public List<DepartmentVo> findDepartTree(String hoscode) {
        List<DepartmentVo> result = new ArrayList<>(18);

        // 1. 通过mongo查询对应的科室列表
        Department departmentQuery= new Department();
        departmentQuery.setHoscode(hoscode);
        Example<Department> example = Example.of(departmentQuery);
        List<Department> departmentList = departmentRepository.findAll(example);

        // 2. 对所有大科室进行分组
        Map<String, List<Department>> departmentMap = departmentList.stream().collect(Collectors.groupingBy(Department::getBigcode));
        // 3. 获取每个大科室下的子科室
        for (Map.Entry<String, List<Department>> entry : departmentMap.entrySet()) {
            // 1 获取大科室编号
            String bigCode = entry.getKey();
            // 2 获取所有大科室
            List<Department> bigDepartmentList = entry.getValue();

            // 封装大科室
            DepartmentVo bigDepartmentVo = new DepartmentVo();
            bigDepartmentVo.setDepcode(bigCode);
            bigDepartmentVo.setDepname(bigDepartmentList.get(0).getDepname());
            
            // 封装子科室列表
            List<DepartmentVo> childrenList = new ArrayList<>(bigDepartmentList.size());
            for (Department childDepartment : bigDepartmentList) {
                DepartmentVo child = new DepartmentVo();
                child.setDepname(childDepartment.getDepname());
                child.setDepcode(childDepartment.getDepcode());
                childrenList.add(child);
            }

            bigDepartmentVo.setChildren(childrenList);
            // 封装数据
            result.add(bigDepartmentVo);
        }
        return result;
    }

    @Override
    public String getDepartName(String hoscode, String depcode) {
        return Optional
                .ofNullable(departmentRepository.getDepartmentByHoscodeAndDepcode(hoscode, depcode))
                .orElseThrow(() -> new MedException(ResultCodeEnum.UNKNOWN_DEPARTMENT))
                .getDepname();
    }
}
